/*
 * Copyright ThinkTank Maths Limited 2006 - 2008
 *
 * This file is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * This file is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this file. If not, see <http://www.gnu.org/licenses/>.
 */
package thinktank.j2me;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

/**
 * Useful J2ME Web-based utility methods which offer some level of similarity to familiar
 * J2SE methods.
 * 
 * @author Samuel Halliday, ThinkTank Maths Limited
 */
public final class TTWebUtils {

	/**
	 * Performs an HTTP POST and cleans up afterwards. Avoids common pitfalls, but
	 * restricts to HTML string data... please be aware of the restrictions placed on the
	 * string data and what should be escaped. At this time, it is the client's
	 * responsibility to ensure that the data complies with the following extracts from
	 * W3:
	 * <ul>
	 * <li>Control names and values are escaped. Space characters are replaced by `+',
	 * and then reserved characters are escaped as described in [RFC1738], section 2.2:
	 * Non-alphanumeric characters are replaced by `%HH', a percent sign and two
	 * hexadecimal digits representing the ASCII code of the character. Line breaks are
	 * represented as "CR LF" pairs (i.e., `%0D%0A').</li>
	 * <li>The control names/values are listed in the order they appear in the document.
	 * The name is separated from the value by `=' and name/value pairs are separated from
	 * each other by `&amp;' (for clarity... the single character ampersand, not the HTML
	 * escaped version).</li>
	 * </ul>
	 * 
	 * @param url
	 * @param mappings
	 *            {@link Object#toString()} will be called on both keys and values, to
	 *            allow for use of {@link StringBuffer} (and possibly more).
	 * @return
	 * @throws IOException
	 * @see http://developers.sun.com/mobility/midp/ttips/HTTPPost/
	 * @see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
	 */
	public static final int httpPost(String url, Hashtable mappings)
			throws IOException {
		if ((url == null) || (mappings == null))
			throw new NullPointerException();
		HttpConnection hcon =
				(HttpConnection) Connector.open(url, Connector.READ_WRITE);
		hcon.setRequestMethod(HttpConnection.POST);
		// RAZR uses this... testing behaviour on server
		// hcon.setRequestProperty("User-Agent", "UNTRUSTED/1.0");
		// allow name=value pairs
		hcon.setRequestProperty("Content-Type",
			"application/x-www-form-urlencoded");
		StringBuffer buf = new StringBuffer();
		// add each of the key/value pairs
		Enumeration keys = mappings.keys();
		while (keys.hasMoreElements()) {
			String key = keys.nextElement().toString();
			String value = mappings.get(key).toString();
			buf.append(key);
			buf.append("=");
			buf.append(value);
			buf.append("&");
		}
		buf.append("\r\n");
		byte[] bytes = buf.toString().getBytes("UTF-8");
		String length = Integer.toString(bytes.length);
		hcon.setRequestProperty("Content-Length", length);
		TTUtils.log("POSTing to " + url);
		OutputStream out = hcon.openOutputStream();
		out.write(bytes);
		// and finish with double newline
		out.close();
		int response = hcon.getResponseCode();
		hcon.close();
		return response;
	}
}
